package com.taskschecker;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
import com.taskschecker.db.DBManager;
import com.taskschecker.db.TaskInfo;

public class TasksCheckerActivity extends Activity {

	private LinearLayout layContent = null;
	private ArrayList<CalendarDayCell> days = new ArrayList<CalendarDayCell>();

	public static Calendar calStartDate = Calendar.getInstance();
	private Calendar calToday = Calendar.getInstance();
	private Calendar calCalendar = Calendar.getInstance();
	private Calendar calSelected = Calendar.getInstance();

	private int currentMonth = 0;
	private int currentYear = 0;
	private int firstDayOfWeek = Calendar.SUNDAY;

	private int calendar_Width = 0;
	private int cell_Width = 0;

	private final static int CALENDAR_HEADER_HEIGHT = 40;
	private final static int CALENDAR_ROW_HEIGHT = 60;

	TextView top_date = null;
	Button btn_pre_month = null;
	Button btn_next_month = null;
	TextView arrange_text = null;
	LinearLayout mainLayout = null;
	LinearLayout arrange_layout = null;

	private List<TaskInfo> taskList;
	private ListView listView;

	TextView selectedDateText = null;

	ArrayList<String> calendar_Source = null;
	Boolean[] flag = null;
	Calendar startDate = null;
	Calendar endDate = null;
	int dayvalue = -1;

	public static int calendar_WeekBgColor = 0;
	public static int calendarHolidayFontColor = 0;
	public static int calendar_WeekFontColor = 0;
	public static int day_BgColor = 0;
	public static int isPresentMonth_FontColor = 0;
	public static int percent_BgColor_0 = 0;
	public static int percent_BgColor_50 = 0;

	public static final int MENU_TASKMANAGE = Menu.FIRST;
	public static final int MENU_CLOSE = Menu.FIRST + 1;

	String userName = "";

	private DBManager mgr;
	
	private AdView adView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mgr = new DBManager(this);

		DisplayMetrics metric = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metric);
		int screenWidth = metric.widthPixels;
		int screenHeight = metric.heightPixels;

		calendar_Width = screenWidth;
		cell_Width = calendar_Width / 7 + 1;

		mainLayout = (LinearLayout) getLayoutInflater().inflate(
				R.layout.activity_tasks_checker, null);
		setContentView(mainLayout);

		top_date = (TextView) findViewById(R.id.top_date);
		btn_pre_month = (Button) findViewById(R.id.btn_pre_month);
		btn_next_month = (Button) findViewById(R.id.btn_next_month);
		btn_pre_month.setOnClickListener(new PreMonthOnClickListener());
		btn_next_month.setOnClickListener(new NextMonthOnClickListener());

		calStartDate = getCalendarStartDate();
		mainLayout.addView(generateCalendarMain());
		CalendarDayCell selectedDay = updateCalendar();

		if (selectedDay != null)
			selectedDay.requestFocus();
		
		LinearLayout.LayoutParams adParams = new LinearLayout.LayoutParams(
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.WRAP_CONTENT);
		LinearLayout adLayout = new LinearLayout(this);
		adLayout.setOrientation(LinearLayout.VERTICAL);
		adView = new AdView(this, AdSize.BANNER, "a1529ae5a373e81");
		//LinearLayout adLayout = (LinearLayout) findViewById(R.id.adLayout);
		adLayout.addView(adView);
		adView.loadAd(new AdRequest());
		mainLayout.addView(adLayout, adParams);

		selectedDateText = new TextView(this);
		selectedDateText.setText(CalendarUtils.getDateStr(selectedDay));
		selectedDateText.setGravity(Gravity.CENTER);
		selectedDateText.setBackgroundColor(Color.parseColor("#EDE8DD"));
		selectedDateText.setTextColor(Color.BLACK);
		selectedDateText.setTextSize(18);
		selectedDateText.setPadding(0, 10, 0, 10);
		mainLayout.addView(selectedDateText);

		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.MATCH_PARENT);
		arrange_text = new TextView(this);
		listView = new ListView(this);
		int selDay = CalendarUtils.getDateInt(selectedDay);
		updateTaskList(selDay);
		listView.setCacheColorHint(0);

		startDate = getStartDate();
		calToday = getTodayDate();
		endDate = getEndDate(startDate);
		
//		RelativeLayout rl = (RelativeLayout)findViewById(R.id.relativeLayout1);
//		params.height = screenHeight - rl.getLayoutParams().height 
//				- CALENDAR_HEADER_HEIGHT - CALENDAR_ROW_HEIGHT * 6 - selectedDateText.getLineHeight() - 130;
		
		mainLayout.addView(listView, params);
		
		

		sendUpdateWidgetBroadcast();

		calendar_WeekBgColor = this.getResources().getColor(
				R.color.Calendar_WeekBgColor);
		isPresentMonth_FontColor = this.getResources().getColor(
				R.color.isPresentMonth_FontColor);
		day_BgColor = this.getResources().getColor(R.color.day_BgColor);
		calendar_WeekFontColor = this.getResources().getColor(
				R.color.Calendar_WeekFontColor);
		calendarHolidayFontColor = this.getResources().getColor(R.color.red);
		percent_BgColor_0 = this.getResources().getColor(R.color.red);
		percent_BgColor_50 = this.getResources().getColor(R.color.yellow);
	}

	private LinearLayout createLayout(int iOrientation) {
		LinearLayout lay = new LinearLayout(this);
		lay.setLayoutParams(new LayoutParams(
				android.view.ViewGroup.LayoutParams.MATCH_PARENT,
				android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
		lay.setOrientation(iOrientation);

		return lay;
	}

	private View generateCalendarMain() {
		layContent = createLayout(LinearLayout.VERTICAL);
		layContent.addView(generateCalendarHeader());
		days.clear();

		for (int iRow = 0; iRow < 6; iRow++) {
			layContent.addView(generateCalendarRow());
		}

		return layContent;
	}

	private View generateCalendarHeader() {
		LinearLayout layRow = createLayout(LinearLayout.HORIZONTAL);

		for (int iDay = 0; iDay < 7; iDay++) {
			CalendarDayHeader day = new CalendarDayHeader(this, cell_Width,
					CALENDAR_HEADER_HEIGHT);

			final int iWeekDay = CalendarUtils.getWeekDay(iDay, firstDayOfWeek);
			day.setData(iWeekDay);
			layRow.addView(day);
		}

		return layRow;
	}

	private View generateCalendarRow() {
		LinearLayout layRow = createLayout(LinearLayout.HORIZONTAL);

		for (int iDay = 0; iDay < 7; iDay++) {
			CalendarDayCell dayCell = new CalendarDayCell(this, cell_Width,
					CALENDAR_ROW_HEIGHT);
			dayCell.setItemClick(clickCell);
			days.add(dayCell);
			layRow.addView(dayCell);
		}
		return layRow;
	}

	private Calendar getCalendarStartDate() {
		calToday.setTimeInMillis(System.currentTimeMillis());
		calToday.setFirstDayOfWeek(firstDayOfWeek);

		if (calSelected.getTimeInMillis() == 0) {
			calStartDate.setTimeInMillis(System.currentTimeMillis());
			calStartDate.setFirstDayOfWeek(firstDayOfWeek);
		} else {
			calStartDate.setTimeInMillis(calSelected.getTimeInMillis());
			calStartDate.setFirstDayOfWeek(firstDayOfWeek);
		}

		updateStartDateForMonth();
		return calStartDate;
	}

	private void updateStartDateForMonth() {
		currentMonth = calStartDate.get(Calendar.MONTH);
		currentYear = calStartDate.get(Calendar.YEAR);
		calStartDate.set(Calendar.DAY_OF_MONTH, 1);
		calStartDate.set(Calendar.HOUR_OF_DAY, 0);
		calStartDate.set(Calendar.MINUTE, 0);
		calStartDate.set(Calendar.SECOND, 0);

		updateCurrentMonthDisplay();

		int day = 0;
		day = calStartDate.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;
		if (day < 0)
			day = 6;

		calStartDate.add(Calendar.DAY_OF_WEEK, -day);
	}

	private CalendarDayCell updateCalendar() {
		CalendarDayCell selectedCell = null;
		boolean isSelected = false;
		final boolean isSelection = (calSelected.getTimeInMillis() != 0);
		final int selectedYear = calSelected.get(Calendar.YEAR);
		final int selectedMonth = calSelected.get(Calendar.MONTH);
		final int selectedDay = calSelected.get(Calendar.DAY_OF_MONTH);
		calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());
		for (int i = 0; i < days.size(); i++) {
			final int year = calCalendar.get(Calendar.YEAR);
			final int month = calCalendar.get(Calendar.MONTH);
			final int day = calCalendar.get(Calendar.DAY_OF_MONTH);
			final int dayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);
			CalendarDayCell dayCell = days.get(i);

			boolean isToday = false;

			if (calToday.get(Calendar.YEAR) == year) {
				if (calToday.get(Calendar.MONTH) == month) {
					if (calToday.get(Calendar.DAY_OF_MONTH) == day) {
						isToday = true;
					}
				}
			}

			boolean isHoliday = false;
			if ((dayOfWeek == Calendar.SATURDAY)
					|| (dayOfWeek == Calendar.SUNDAY))
				isHoliday = true;

			isSelected = false;

			if (isSelection)
				if ((selectedDay == day) && (selectedMonth == month)
						&& (selectedYear == year)) {
					isSelected = true;
				}

			dayCell.setSelected(isSelected);

			if (isSelected)
				selectedCell = dayCell;

			dayCell.setData(year, month, day, isToday, isHoliday, currentMonth,
					getDayPercent(year, month, day, currentMonth));

			calCalendar.add(Calendar.DAY_OF_MONTH, 1);
		}
		layContent.invalidate();

		return selectedCell;
	}

	private void updateCurrentMonthDisplay() {
		String date = calStartDate.get(Calendar.YEAR) + "年"
				+ (calStartDate.get(Calendar.MONTH) + 1) + "月";
		top_date.setText(date);
	}

	class PreMonthOnClickListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			selectedDateText.setText("");
			arrange_text.setText("");
			calSelected.setTimeInMillis(0);
			currentMonth--;

			if (currentMonth == -1) {
				currentMonth = 11;
				currentYear--;
			}

			calStartDate.set(Calendar.DAY_OF_MONTH, 1);
			calStartDate.set(Calendar.MONTH, currentMonth);
			calStartDate.set(Calendar.YEAR, currentYear);
			calStartDate.set(Calendar.HOUR_OF_DAY, 0);
			calStartDate.set(Calendar.MINUTE, 0);
			calStartDate.set(Calendar.SECOND, 0);
			calStartDate.set(Calendar.MILLISECOND, 0);
			updateStartDateForMonth();

			startDate = (Calendar) calStartDate.clone();
			endDate = getEndDate(startDate);

			updateCalendar();
			updateTaskList(-1);
		}

	}

	class NextMonthOnClickListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			selectedDateText.setText("");
			arrange_text.setText("");
			calSelected.setTimeInMillis(0);
			currentMonth++;

			if (currentMonth == 12) {
				currentMonth = 0;
				currentYear++;
			}

			calStartDate.set(Calendar.DAY_OF_MONTH, 1);
			calStartDate.set(Calendar.MONTH, currentMonth);
			calStartDate.set(Calendar.YEAR, currentYear);
			updateStartDateForMonth();

			startDate = (Calendar) calStartDate.clone();
			endDate = getEndDate(startDate);

			updateCalendar();
			updateTaskList(-1);

		}
	}

	private CalendarDayCell.OnItemClick clickCell = new CalendarDayCell.OnItemClick() {
		public void OnClick(CalendarDayCell item) {
			calSelected.setTimeInMillis(item.getDate().getTimeInMillis());

			selectedDateText.setBackgroundColor(Color.parseColor("#EDE8DD"));
			selectedDateText.setText(CalendarUtils.getDateStr(item));

			int selDay = CalendarUtils.getDateInt(item);
			updateTaskList(selDay);

			item.setSelected(true);
			updateCalendar();
		}
	};

	public Calendar getTodayDate() {
		Calendar today = Calendar.getInstance();
		today.set(Calendar.HOUR_OF_DAY, 0);
		today.set(Calendar.MINUTE, 0);
		today.set(Calendar.SECOND, 0);
		today.setFirstDayOfWeek(firstDayOfWeek);

		return today;
	}

	public Calendar getStartDate() {
		int i = 0;
		Calendar startDate = Calendar.getInstance();
		startDate.set(Calendar.DAY_OF_MONTH, 1);
		startDate.set(Calendar.HOUR_OF_DAY, 0);
		startDate.set(Calendar.MINUTE, 0);
		startDate.set(Calendar.SECOND, 0);
		startDate.setFirstDayOfWeek(firstDayOfWeek);

		i = startDate.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;

		if (i < 0) {
			i = 6;
		}

		startDate.add(Calendar.DAY_OF_WEEK, -i);

		return startDate;
	}

	public Calendar getEndDate(Calendar startDate) {
		Calendar endDate = Calendar.getInstance();
		endDate = (Calendar) startDate.clone();
		endDate.add(Calendar.DAY_OF_MONTH, 41);
		return endDate;
	}

	private List<TaskInfo> getData(Integer selectDate) {
		return mgr.getTaskInfoListByDate(selectDate);
	}

	public final class ViewHolder {
		public Button sts_btn;
		public TextView content;
		public Button delete_btn;
	}

	public class MyAdapter extends BaseAdapter {

		private LayoutInflater lInflater;

		public MyAdapter(Context context) {
			this.lInflater = LayoutInflater.from(context);
		}

		@Override
		public int getCount() {
			return taskList.size();
		}

		@Override
		public Object getItem(int arg0) {
			return null;
		}

		@Override
		public long getItemId(int arg0) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			ViewHolder holder = null;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = lInflater.inflate(R.layout.task_list_item, null);
				holder.sts_btn = (Button) convertView
						.findViewById(R.id.sts_btn);
				holder.content = (TextView) convertView
						.findViewById(R.id.content);
				holder.delete_btn = (Button) convertView
						.findViewById(R.id.delete_btn);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			if (taskList.get(position).getCompleteness() == 0) {
				holder.sts_btn.setBackgroundResource(R.drawable.unfinished);
			} else if (taskList.get(position).getCompleteness() == 1) {
				holder.sts_btn.setBackgroundResource(R.drawable.finished);
			}

			final int index = position;
			holder.sts_btn.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					TaskInfo param = new TaskInfo();
					param.setTaskid(taskList.get(index).getTaskid());
					if (taskList.get(index).getCompleteness() == 0) {
						param.setCompleteness(1);
					} else {
						param.setCompleteness(0);
					}
					mgr.updateCompleteness(param);
					updateTaskList(taskList.get(index).getDate());
					updateCalendar();
					sendUpdateWidgetBroadcast();
				}
			});

			holder.content.setText(taskList.get(position).getContent());

			holder.delete_btn.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							TasksCheckerActivity.this);
					builder.setMessage(getResources().getString(
							R.string.alert_delete_task));
					builder.setCancelable(false);
					builder.setPositiveButton("YES",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									TaskInfo param = new TaskInfo();
									param.setTaskid(taskList.get(index)
											.getTaskid());
									mgr.deleteTaskInfo(param);
									updateTaskList(taskList.get(index)
											.getDate());
									updateCalendar();
									sendUpdateWidgetBroadcast();
								}
							});
					builder.setNegativeButton("NO",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									dialog.cancel();
								}
							});
					builder.create().show();
				}
			});

			return convertView;
		}

	}

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem item1 = menu.add(0, MENU_TASKMANAGE, 0, R.string.task_manage);
		item1.setIcon(android.R.drawable.ic_menu_manage);
		MenuItem item2 = menu.add(0, MENU_CLOSE, 0, R.string.closed);
		item2.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
		return super.onCreateOptionsMenu(menu);
	}

	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_TASKMANAGE:
			Intent intent = new Intent(TasksCheckerActivity.this,
					TaskGroupListActivity.class);
			startActivity(intent);
			break;
		case MENU_CLOSE:
			finish();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void updateTaskList(int selDay) {
		if (selDay == -1) {
			listView.setAdapter(null);
		} else {
			taskList = getData(selDay);
			MyAdapter adapter = new MyAdapter(getApplicationContext());
			listView.setAdapter(adapter);
		}
	}

	private String getDayPercent(int year, int month, int day, int currentMonth) {
		if (month != currentMonth) {
			return "";
		}
		int tmpDay = CalendarUtils.getDateInt(year, month, day);
		List<TaskInfo> tmpTaskList = getData(tmpDay);
		double compCnt = 0;
		double cnt = 0;
		for (TaskInfo info : tmpTaskList) {
			cnt++;
			if (info.getCompleteness() == 1) {
				compCnt++;
			}
		}
		if (cnt == 0)
			return "";
		double rate = compCnt / cnt;
		DecimalFormat df = new DecimalFormat("##%");
		return df.format(rate);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mgr.closeDB();
		adView.destroy();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		CalendarDayCell selectedDay = updateCalendar();
		int selDay = CalendarUtils.getDateInt(selectedDay);
		updateTaskList(selDay);
	}

	public void sendUpdateWidgetBroadcast() {
		Intent intent = new Intent();
		intent.setAction("cmn.taskschecker.widget.update");
		getApplicationContext().sendBroadcast(intent);
	}

}
